<?php
/**
 * Created by PhpStorm.
 * User: JHR
 * Date: 2018/10/4
 * Time: 10:50
 */
namespace app\api\controller;
use my\MyRedis;
use think\Db;
class Wechatpay extends Base {

    //直接支付、待支付订单支付、联合订单号支付
    public function pay() {
        $post['pay_order_sn'] = input('post.pay_order_sn');
        $post['openid'] = input('post.openid');
        checkPost($post);
        $pay_order_sn = $post['pay_order_sn'];
        try {
            $whereOrder = [
                ['pay_order_sn','=',$pay_order_sn],
                ['uid','=',$this->userinfo['uid']],
                ['status','=',0],
                ['del','=',0]
            ];
            $order_exist = Db::table('mp_food_order')->where($whereOrder)->find();
            if(!$order_exist) {
                return ajax('订单已失效',23);
            }
            if($order_exist['status'] != 0) {
                return ajax('订单已支付, 不可重复发起',28);
            }
        } catch (\Exception $e) {
            mylog($this->cmd,$e->getMessage());
            return ajax($e->getMessage(),-1);
        }
        $config = [
            'appid' => config('appid'),
            'secret' => config('app_secret'),
            'mch_id' => config('mch_id'),
            'key' => config('mch_key'),
            'cert_path' => config('cert_path'),
            'key_path' =>  config('key_path'),
        ];
        $option = [
            'appid' => $config['appid'],
            'mch_id' => $config['mch_id'],
            'nonce_str' => randomkeys(32),
            'sign_type' => 'MD5',
            'body' => '多拉贡快餐',
            'out_trade_no' => $pay_order_sn,
            'total_fee' => floatval($order_exist['pay_price'])*100,
            'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
            'notify_url' => $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . "/api/wechatpay/order_notify",
            'trade_type' => 'JSAPI',
            'openid' => $post['openid']
        ];
        $option['sign'] = getSign($option,$config['key']);
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $result = curl_post_data($url, array2xml($option));
        $result = xml2array($result);
        if($result['return_code'] != 'SUCCESS' || $result['result_code'] != 'SUCCESS') {
            mylog($this->cmd,var_export($result,true),'wxpay_error.log');
            return ajax($result['err_code_des'],29,$result['err_code_des']);
        }
        $prepay['appId'] = $option['appid'];
        $prepay['timeStamp'] = strval(time());
        $prepay['nonceStr'] = $option['nonce_str'];
        $prepay['signType'] = $option['sign_type'];
        $prepay['package'] = 'prepay_id=' . $result['prepay_id'];
        $prepay['paySign'] = getSign($prepay,$config['key']);
        return ajax($prepay);
    }

    public function h5pay() {
        $post['pay_order_sn'] = input('post.pay_order_sn');
        checkPost($post);
        $pay_order_sn = $post['pay_order_sn'];
        try {
            $whereOrder = [
                ['pay_order_sn','=',$pay_order_sn],
                ['status','=',0],
                ['del','=',0]
            ];
            $order_exist = Db::table('mp_food_order')->where($whereOrder)->find();
            if(!$order_exist) {
                return ajax('订单不存在',27);
            }
            if($order_exist['status'] != 0) {
                return ajax('订单已支付, 不可重复发起',28);
            }
        } catch (\Exception $e) {
            mylog($this->cmd,$e->getMessage());
            return ajax($e->getMessage(),-1);
        }
        $config = [
            'appid' => config('appid'),
            'secret' => config('app_secret'),
            'mch_id' => config('mch_id'),
            'key' => config('mch_key'),
            'cert_path' => config('cert_path'),
            'key_path' =>  config('key_path'),
        ];
        $option = [
            'appid' => $config['appid'],
            'mch_id' => $config['mch_id'],
            'nonce_str' => randomkeys(32),
            'sign_type' => 'MD5',
            'body' => '多拉贡快餐',
            'out_trade_no' => $pay_order_sn,
            'total_fee' => floatval($order_exist['pay_price'])*100,
            'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
            'notify_url' => $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . "/api/wechatpay/order_notify",
            'trade_type' => 'MWEB'
        ];
        $scene_info = [
            'h5_info' => [
                'type' => 'Wap',
                'wap_url' => $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'],
                'wap_name' => '多拉贡软件'
            ]
        ];
        $option['scene_info'] = json_encode($scene_info);
        $option['sign'] = getSign($option,$config['key']);
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $result = curl_post_data($url, array2xml($option));
        $result = xml2array($result);
        if($result['return_code'] != 'SUCCESS' || $result['result_code'] != 'SUCCESS') {
            mylog($this->cmd,$pay_order_sn,'wxpay_error.log');
            mylog($this->cmd,var_export($result,true),'wxpay_error.log');
            return ajax($result['err_code_des'],29,$result['err_code_des']);
        }
        return ajax($result);

    }
    //订单支付回调接口
    public function order_notify()
    {
        //将返回的XML格式的参数转换成php数组格式
        $xml = file_get_contents('php://input');
        $data = xml2array($xml);
        mylog($this->cmd, var_export($data, true), 'wxpay.log');
        if ($data) {
            if ($data['return_code'] == 'SUCCESS' && $data['result_code'] == 'SUCCESS') {
                $whereOrder = [
                    ['status', '=', 0],
                    ['pay_order_sn', '=', $data['out_trade_no']]
                ];
                $order_exist = Db::table('mp_food_order')->where($whereOrder)->find();
                $time = time();
                if ($order_exist) {
                    $update_order_data = [
                        'status' => 1,
                        'trans_id' => $data['transaction_id'],
                        'wx_openid' => $data['openid'],
                        'pay_time' => $time,
                        'type' => 1
                    ];
                    Db::table('mp_food_order')->where($whereOrder)->update($update_order_data);
                    $whereDetail = [
                        ['order_id','=',$order_exist['id']]
                    ];
                    $order_detail = Db::table('mp_food_order_detail')->where($whereDetail)->field('food_name,num,total_price')->select();
                    $event = "food_order" . $order_exist['shop_id'];
                    $array = [
                        'order_id' => $order_exist['id'],
                        'shop_name' => $order_exist['shop_name'],
                        'table_no' => $order_exist['table_no'],
                        'number' => $order_exist['number'],
                        'pay_price' => $order_exist['pay_price'],
                        'pay_time' => $time,
                        'pay_order_sn' => $order_exist['pay_order_sn'],
                        'desc' => $order_exist['desc'],
                        'detail' => $order_detail
                    ];
                    mylog($this->cmd,var_export($array,true),'printer.log');
                    $this->emit($event,$array);
                }
            }
            exit(array2xml(['return_code' => 'SUCCESS', 'return_msg' => 'OK']));
        }

    }
    //退款
    public function refund() {
        $post['pay_order_sn'] = input('post.pay_order_sn');
        checkPost($post);
        $out_refund_no = 'r' . create_unique_number();
        $pay_order_sn = $post['pay_order_sn'];
        try {
            $whereOrder = [
                ['pay_order_sn','=',$pay_order_sn],
                ['uid','=',$this->userinfo['uid']],
                ['type','=',1]
            ];
            $order_exist = Db::table('mp_food_order')->where($whereOrder)->find();
            if(!$order_exist) {
                return ajax('订单不存在',27);
            }
            if($order_exist['status'] != 1) {
                return ajax('订单当前状态无法退款',40);
            }
        } catch (\Exception $e) {
            mylog($this->cmd,$e->getMessage());
            return ajax($e->getMessage(),-1);
        }
        $options = [
            'appid' => config('appid'),
            'mch_id'=> config('mch_id'),
            'nonce_str'=>randomkeys(32),
            'sign_type'=>'MD5',
            'transaction_id'=> $order_exist['trans_id'],
            'out_trade_no'=> $pay_order_sn,
            'out_refund_no'=> $out_refund_no,
            'total_fee'=> floatval($order_exist['pay_price'])*100,
            'refund_fee'=> floatval($order_exist['pay_price'])*100,
            'refund_fee_type'=> 'CNY',
            'refund_desc'=> '商品无货',
            'notify_url'=> $_SERVER['REQUEST_SCHEME'] . '://'.$_SERVER['HTTP_HOST'].'/api/wechatpay/refund_notify',
            'refund_account' => 'REFUND_SOURCE_UNSETTLED_FUNDS'
        ];
        $options['sign'] = getSign($options,config('mch_key'));
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
        $res = curl_post_data($url,array2xml($options),true);
        $result = xml2array($res);
        mylog($this->cmd, var_export($result, true), 'wx_refund.log');
        if($result && $result['return_code'] == 'SUCCESS') {
            if($result['result_code'] == 'SUCCESS') {
                Db::table('mp_food_order')->where($whereOrder)->update([
                    'refund' => 2,
                    'refund_no' => $out_refund_no,
                    'refund_apply_time' => time(),
                    'refund_time' => time()
                ]);
            }else {
                return ajax($result['err_code_des'],-1,$result['err_code_des']);
            }
        }else {
            return ajax('退款失败',-1);
        }
        return ajax();
    }

    public function refund_notify() {
        $xml = file_get_contents('php://input');
        $data = xml2array($xml);
        mylog($this->cmd, var_export($data, true), 'wx_refund_notify.log');
    }


    private function emit($event ,$message) {
        $data = [$event,$message];
        $object = json_decode('{}');
        $array = [
            "emitter",
            [
                'type' => 2,
                'data' => $data,
                'nsp' => '/'
            ],
            [
                'rooms' => [],
                'flags' => $object,
                'except' => []
            ],
        ];
        $publish_data = msgpack_pack($array);
        $redis = MyRedis::getInstance();
        $res = $redis::publish('socket.io#/#',$publish_data);
        return $res;
    }




}